#pragma once
#include "lexer.h"

class Node {

};

class Expr : public Node {
public:
	Expr(int type);
	Expr(Token* op);
	Expr();
public:
	Token* op;
	Token::TokenType type;
	virtual Expr* reduce();
	virtual Expr* gen();
	virtual std::string toString();
};

class Op : public Expr {
public:
	Op();
	Op(Token* op);
	Expr* reduce() override;
};

class Temp : public Expr {
public:
	static int count;
	int number;
	Temp();
	std::string toString() override;
};

class Arith : public Op {
private:
	Expr *expr1, *expr2;
public:
	Arith(Token* op, Expr *e1, Expr *e2);
	Expr* gen() override;
	std::string toString() override;
};

class Stmt : public Node {
public:
	Token* op;
	Stmt(Token* op);
	static Stmt* null;
	virtual std::string toString();
	virtual void gen();
};

class Assign : public Stmt {
public:
	Expr* id, * eval;
	Assign(Expr* id, Expr* eval);
	std::string toString() override;
	void gen() override;
};

class Seq : public Stmt {
public:
	Stmt* s1, * s2;
	Seq(Stmt* s1, Stmt* s2);
	void gen() override;
};